
exports.GAResourceDownloader = Core.Class.subclass({
	
	initialize: function(storeObject, successCb, failureCb, resourceType, useCache) {
		this._useCache = (typeof useCache == 'undefined') ? true : useCache;
		this._resourceType = resourceType;		
		this._storeObject = storeObject;
		this._storeObjectKey = GACommonUtils.getKeyForStoreObject(this._storeObject);		
		this._resource = GAResourceUtils.getResourceOfType(storeObject, resourceType);
		this._failureCb = failureCb;
		this._destroyed = false;
		if (typeof this._resource != 'undefined' && this._resource != null) {
			this._successCb = successCb;
			this._savePath = GAResourceUtils.getResourceSavePath(storeObject, this._resource);
			this._keyPath = this._savePath + this._resource.type + ".key";
				this._downloadPath = this.constructPath(this._savePath);
			this._fileDownloder = null;
		}
		else {
			this._failureCb(kGAStatusType.kGAResourceObjectNil, "Store object does not have a resource of type: " + resourceType);
		}
	},
	
	constructPath: function(basePath) {
		var path = [];
		path.push(basePath);
		var fileName = (this._resource.type == GAResourceType.kThumb) ? "thumb" : this._resource.name;
		path.push(fileName);
		path.push(".");
		path.push(this._resource.filetype);
		return path.join("");
	},
	
	startDownloading: function() {
		if (typeof this._resource != 'undefined' && this._resource != null) {
			if (this._useCache == true) {
				if (GAGameLoader.isResourceAvailable(this._storeObjectKey, this._resourceType) == false) {
					Storage.FileSystem.readFile(this._keyPath, false, this.keyCheck.bind(this));
				}
				else {					
					this._successCb(this._savePath, true);
				}
			}
			else {
				Storage.FileSystem.readFile(this._keyPath, false, this.keyCheck.bind(this));
			}
		}
	},
	
	keyCheck: function(error, contents) {
		if(!this._destroyed){
		if (error || (!error && contents == null)) { //Key is probably not present or invalid, so download this resource
			this.downloadResource();
		}
		else {
			if (contents != this._resource.id) {	// keys do not match, so download this resource
				this.downloadResource();
			}
			else {	// keys match, so no need to download
				GAGameLoader.addToDownloadedResources(this._storeObjectKey, this._resourceType);
				this._successCb(this._savePath, false);
			}
		}
		}
	},
	
	getPathForObject: function(storeObject) {
		var path = [];
		if (storeObject.objectType == "store") {
			path.push(storeObject.id);
		}
		else if (storeObject.objectType == "cat") {
			path.push(storeObject.parent.id);
			path.push(storeObject.id);
		}
		else if (storeObject.objectType == "item") {
			path.push(storeObject.parent.parent.id);
			path.push(storeObject.parent.id);
			path.push(storeObject.id);
		}
		return path.join("/");
	},
	
	getUrl: function() {
		var storeHandler = GAGameLoader.getStoreHandler();
		var url = [];
		url.push(GAGameLoader.getResponseObject().getStoreServer());
		/*
		 * The logic for constructing the URL is different for QA users because of the following reason...
		 * In case of QA users, the server store url contains a vmart base url instead of GAE. In vmart, when you fetch
		 * a resource (either thumb or default_zip) there is an internal redirection that happens on the server side.
		 * ngCore's DownloadFile is not capable of handling url redirections and therefore fails. As a word around, we
		 * are instead fetching the resource directly from the "redirected url".
		 * TODO: Whenever ngCore's DownloadFile starts supporting url redirection, we should revise this logic to simply things!  
		 */
		if (GAGameLoader.getResponseObject().isQAUser()) {
			var parts = [];
			parts.push("clientmedia/uploaded_images");
			parts.push(storeHandler.getCompanyId());
			parts.push(storeHandler.getGameId());
			parts.push(this.getPathForObject(this._storeObject));
			parts.push(this._resource.id);
			url.push(parts.join("/"));
			url.push(".");
			url.push(this._resource.filetype);
		}
		else {
			 url.push("image?key=");
			 url.push(this._resource.id);	
		}
		return url.join("");
	},
	invalidate: function()
	{
		if(this._fileDownloader)
			this._fileDownloader.invalidate();
	},
	downloadResource: function() {
		var url = this.getUrl();
		url = encodeURI(url);
		//console.log("Downloading resource from: " + url);
		this._fileDownloader = new GAFileDownloader(this._downloadPath, 'GET', url, null, this);
		this._fileDownloader.startDownloading();
	},

	onDownloadSuccess: function(fileDownloader, fileSignature){
		try {
			if( fileDownloader != null) {
				fileDownloader.destroy();
				fileDownloader = null;
			}
			if (this._resource.filetype == "zip") {
				Storage.FileSystem.decompressFile(this._downloadPath, this._savePath, true, this.decompressCompleted.bind(this));
			}
			else {
				this.updateKey();
			}
		}
		catch(exception){
			this._failureCb(kGAStatusType.kGAZipExtractionFailedWithUnknownException, "Unzipping failed");
		}
	},
	
	onDownloadFailure: function(fileDownloader, errorCode) {
		if( fileDownloader != null){
			fileDownloader.destroy();
			fileDownloader = null;
		}
		this._failureCb(kGAStatusType.kGAResourceDownloadingFailed, errorCode);
	},
	
	decompressCompleted : function(error, files){
		var fileName = "";
		if(error == ""){
			Storage.FileSystem.deleteFile(this._downloadPath);
			Storage.FileSystem.writeFile(this._keyPath, this._resource.id, false, this.updateKey.bind(this));
		}
		else{
			this._failureCb(kGAStatusType.kGAZipExtractionFailedWithUnknownException, error);
		}
	},
	
	updateKey: function() {
		Storage.FileSystem.writeFile(this._keyPath, this._resource.id, false, this.keyUpdated.bind(this));		
	},
	
	keyUpdated: function() {
        GAGameLoader.addToDownloadedResources(this._storeObjectKey, this._resourceType);		
        
        if(this._successCb) {
            this._successCb(this._savePath, true);
        }
	},
	
	destroy: function() {
		this._destroyed = true;
		this._storeObject = null;
		this._failureCb = null;
		if (typeof this._resource != 'undefined' && this._resource != null) {
			this._resource = null;
			this._successCb = null;
			this._resourceType = null;
			this._savePath = null;
			this._keyPath = null;
			this._downloadPath = null;
			if( this._fileDownloader != null){
				this._fileDownloader.destroy();
				this._fileDownloader = null;
			}
		}
	}
	
	
});